This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / routes / camo / [hex] / +server.ts
1.2 kB 39 lines
1import { createHmac } from "node:crypto"; 2import { error } from "@sveltejs/kit"; 3import { getConfig } from "$lib/server/config"; 4import type { RequestHandler } from "./$types"; 5 6// the signed url only changes when the secret does, so it can cache for a day 7const MAX_AGE = 86400; 8 9const HEX = /^(?:[0-9a-f]{2})+$/; 10 11export const GET: RequestHandler = ({ params }) => { 12 const hex = params.hex.toLowerCase(); 13 if (!HEX.test(hex)) error(400, "Not a camo url"); 14 15 const target = Buffer.from(hex, "hex").toString("utf8"); 16 let parsed: URL; 17 try { 18 parsed = new URL(target); 19 } catch { 20 error(400, "Not a camo url"); 21 } 22 if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { 23 error(400, "Not a camo url"); 24 } 25 26 // redirecting unsigned would make this an open redirect, so no secret means 27 // no images at all 28 const { camoUrl, camoSecret } = getConfig(); 29 if (!camoSecret) error(404, "Camo is not configured"); 30 31 const signature = createHmac("sha256", camoSecret).update(target).digest("hex"); 32 return new Response(null, { 33 status: 302, 34 headers: { 35 location: `${camoUrl}/${signature}/${hex}`, 36 "cache-control": `public, max-age=${MAX_AGE}` 37 } 38 }); 39};